
local lg = love.graphics;

local floor = math.floor;
local ceil = math.ceil;
local pow = math.pow;

local show_shadow = true;

local colortable = 
{
	background = {255,255,255,220},
	
	slider_bg = {255,255,255,200},
	slider_bar = {
		{200,200,200,200},	-- normal
		{200,200,200,255}, 	-- hover
		{200,200,200,225},	-- click
	},
	button = {
		{250,250,250,200},	-- normal
		{250,250,250,255}, 	-- hover
		{255,255,255,225},	-- click
	}
}

uitable = 
{
	gen_diamond_wnd = nil,
	heightmap_option = nil,
	perlin_option = nil,
	gen_perlin_wnd = nil;
	
	terrain_wnd = nil,
	terrain_option = nil,
};

function GenDiamondWnd(graph)
	local cw, ch = 220, 70;
	local iw, ih = 0, 0;
	local wndbg_w, wndbg_h = 0, 0;

	graph:createCanvas("GenDiamondWnd", cw, ch);
	wndbg_w, wndbg_h = graph:getImageSize("wndbg");
	iw, ih = graph:getImageSize("normal");
	
	local gui = Girl.Gui((lg.getWidth()-cw)/2, (lg.getHeight()-ch)/2, 
		cw, ch, graph, "GenDiamondWnd");
	
	local background = Girl.View.Picture(cw, ch);
	background:setImage("wndbg");
	background:setImageColor(colortable.background);
	background:setMode(2,{x=20, y=20, width=6, height=6}, wndbg_w, wndbg_h);
	background:enableCaption(true);
	gui:add("bg", background, 0, 0);
	
	local caption = Girl.View.Label(180,16);
	caption:setFont("font12");
	caption:setLabel("Generating Diamond Noise");
	caption.parent_mouse_event = true;
	background:add(nil, caption, 2, 2);
	
	local text = Girl.View.Label(208,12);
	text:setFont("font10");
	text:setAlign(text.AlignEnum.center);
	text:setLabel("Status Status Status");
	gui:add("status", text, 6, 24);
	
	local btn = Girl.View.Button(60, 16);
	btn:setFont("font10");
	btn:setImage("normal", "normal", "click");
	btn:setLabel("Cancel", 12, 1);
	btn:setImageColor(unpack(colortable.button));
	btn:setMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
	btn.onButtonClick = function (this)
		idle:clearTask("GenDiamondNoise");
		gui:close(1)
		gm:enableModelmode(false);
	end
	background:add(nil, btn, 80, 42);
	
	gui:showGui(false);
	gui:enableGui(false);
	
	uitable.gen_diamond_wnd = gui;
	return "GenDiamondWnd", gui;
end

function GenPerlinWnd(graph)
	local cw, ch = 220, 70;
	local iw, ih = 0, 0;
	local wndbg_w, wndbg_h = 0, 0;

	graph:createCanvas("GenPerlinWnd", cw, ch);
	wndbg_w, wndbg_h = graph:getImageSize("wndbg");
	iw, ih = graph:getImageSize("normal");
	
	local gui = Girl.Gui((lg.getWidth()-cw)/2, (lg.getHeight()-ch)/2, 
		cw, ch, graph, "GenPerlinWnd");
	
	local background = Girl.View.Picture(cw, ch);
	background:setImage("wndbg");
	background:setImageColor(colortable.background);
	background:setMode(2,{x=20, y=20, width=6, height=6}, wndbg_w, wndbg_h);
	background:enableCaption(true);
	gui:add("bg", background, 0, 0);
	
	local caption = Girl.View.Label(180,16);
	caption:setFont("font12");
	caption:setLabel("Generating Perlin Noise");
	caption.parent_mouse_event = true;
	background:add(nil, caption, 2, 2);
	
	local initProgress = function ()
		local slider = Girl.View.Slider(200, 14);
		slider:setValue(0);
		slider:setBackground("click");
		slider:setBackgroundColor(colortable.slider_bg);
		slider:setBackgroundMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		slider:setMode(slider.TypeModeEnum.horizontal,1);
		slider:setSliderRect(2, 2, 196, 9);
		slider:setSliderColor({125,125,125},{125,125,125},{125,125,125});
		background:add("progress", slider, 10, 22);
		
		local value = Girl.View.Label(slider:getSize());
		value:setFont("font10");
		value:setLabel("0 %");
		value:setAlign(value.AlignEnum.center);
		value.parent_mouse_event = true;
		slider:add(nil, value, 0, 0);
		
		slider.onValueChange = function (this)
			local v = floor(slider:getValue()*100);
			value:setLabel(v.." %")
		end
	end
	initProgress();
	
	local btn = Girl.View.Button(60, 16);
	btn:setFont("font10");
	btn:setImage("normal", "normal", "click");
	btn:setLabel("Cancel", 12, 1);
	btn:setImageColor(unpack(colortable.button));
	btn:setMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
	btn.onButtonClick = function (this)
		idle:clearTask("GenPerlinNoise");
		gui:close(1)
		gm:enableModelmode(false);
	end
	background:add(nil, btn, 80, 42);
	
	gui:showGui(false);
	gui:enableGui(false);
	
	uitable.gen_perlin_wnd = gui;
	return "GenPerlinWnd", gui;
end

function HeightMapOptionWnd(graph)
	local cw, ch = 200, 340
	local iw, ih = 0, 0;
	local wndbg_w, wndbg_h = 0, 0;
	local diamond = TerrainToy.diamond;
	local heightmap = TerrainToy.heightmap;
	local tag = "HeightMapOption"
	
	graph:createCanvas("DiamondOption", cw, ch);
	graph:createCanvas("DiamondNoise", 256, 256);
	wndbg_w, wndbg_h = graph:getImageSize("wndbg");
	iw, ih = graph:getImageSize("normal");
	
	local gui = Girl.Gui(0, 0, cw, ch, graph, "DiamondOption");
	
	local background = Girl.View.Picture(cw, ch);
	background:setImage("wndbg");
	background:setImageColor(colortable.background);
	background:setMode(2,{x=20, y=20, width=6, height=6}, wndbg_w, wndbg_h);
	background:enableCaption(true);
	gui:add("bg", background, 0, 0);
	
	local caption = Girl.View.Label(120,16);
	caption:setFont("font12");
	caption:setLabel("Diamond Option");
	caption.parent_mouse_event = true;
	background:add(nil, caption, 2, 2);
	
	local initRoughness = function ()
		local slider = Girl.View.Slider(100, 14);
		slider:setValue(.25);
		slider:setBackground("click");
		slider:setBackgroundColor(colortable.slider_bg);
		slider:setBackgroundMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		slider:setMode(slider.TypeModeEnum.horizontal,2);
		slider:setSliderRect(8, 1, 84, 11);
		slider:setSliderImage("normal");
		slider:setSliderSize(14,11)
		slider:setSliderColor(unpack(colortable.slider_bar));
		background:add(nil, slider, 70, 25);
		
		local text = Girl.View.Label(60,12);
		text:setFont("font10");
		text:setLabel("Roughness :");
		background:add(nil, text, 6, 24);
		
		local value = Girl.View.Label(30, 12);
		value:setFont("font10");
		value:setAlign(value.AlignEnum.right);
		background:add(nil, value, 160, 25);

		slider.onValueChange = function (this)
			local v = floor(slider:getValue()*19+1);
			value:setLabel(v);
			diamond.roughness = v;
		end
		slider:onValueChange();
	end
	initRoughness();
	
	local initUnitSize = function ()
		local slider = Girl.View.Slider(100, 14);
		slider:setValue(0);
		slider:setWheelStep(.33);
		slider:setBackground("click");
		slider:setBackgroundColor(colortable.slider_bg);
		slider:setBackgroundMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		slider:setMode(slider.TypeModeEnum.horizontal,2);
		slider:setSliderRect(8, 1, 84, 11);
		slider:setSliderImage("normal");
		slider:setSliderSize(14, 11)
		slider:setSliderColor(unpack(colortable.slider_bar));
		background:add(nil, slider, 70, 45);
		
		local text = Girl.View.Label(60,12);
		text:setFont("font10");
		text:setLabel("Unit size :");
		background:add(nil, text, 6, 44);
		
		local value = Girl.View.Label(30, 12);
		value:setFont("font10");
		value:setAlign(value.AlignEnum.right);
		background:add(nil, value, 160, 45);

		slider.onValueChange = function (this)
			local v = pow(2,floor(slider:getValue()*3));
			value:setLabel(v);
			diamond.unit_size = v;
			heightmap.unit_size = v;
		end
		slider:onValueChange();
	end
	initUnitSize();
	
	local initSize = function ()
		local slider = Girl.View.Slider(100, 14);
		slider:setValue(0.5);
		slider:setWheelStep(.5);
		slider:setBackground("click");
		slider:setBackgroundColor(colortable.slider_bg);
		slider:setBackgroundMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		slider:setMode(slider.TypeModeEnum.horizontal,2);
		slider:setSliderRect(8, 1, 84, 11);
		slider:setSliderImage("normal");
		slider:setSliderSize(14, 11)
		slider:setSliderColor(unpack(colortable.slider_bar));
		background:add(nil, slider, 70, 65);
		
		local text = Girl.View.Label(60,12);
		text:setFont("font10");
		text:setLabel("Size :");
		background:add(nil, text, 6, 64);
		
		local value = Girl.View.Label(30, 12);
		value:setFont("font10");
		value:setAlign(value.AlignEnum.right);
		background:add(nil, value, 160, 65);

		slider.onValueChange = function (this)
			local v = pow(2,floor(slider:getValue()*2))*128;
			value:setLabel(v);
			diamond.map_dimension = v;
		end
		slider:onValueChange();
	end
	initSize();
	
	local initRandomSeed = function()
		local text = Girl.View.Label(60,12);
		text:setFont("font10");
		text:setLabel("Rand Seed :");
		background:add(nil, text, 6, 85);
	
		local editbox = Girl.View.EditBox(120, 14);
		editbox:setFont("font10");
		editbox:setBorder("click");
		editbox:setBorderColor(colortable.slider_bg);
		editbox:setMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		editbox:setTextRect(2,0, 120-4, 14)
		editbox:setLimit(true, 10);
		editbox.onTextChange = function (this)
			TerrainToy.diamond_seed = tonumber(this:getText());
		end
		background:add(nil, editbox, 70, 85);
	end
	initRandomSeed();
	
	local initConsecutive = function ()
		local btnh = Girl.View.Button(90, 16);
		btnh:setFont("font10");
		btnh:setImage("normal", "normal", "click");
		btnh:setLabel("ContinuousH:"..((diamond.consecutive_h and "on") or "off"), 3, 1);
		btnh:setImageColor(unpack(colortable.button));
		btnh:setMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		btnh.onButtonClick = function (this)
			diamond.consecutive_h = not diamond.consecutive_h;
			btnh:setLabel("ContinuousH:"..((diamond.consecutive_h and "on") or "off"), 3, 1);
		end
		background:add(nil, btnh, 9, 105);
		
		local btnv = Girl.View.Button(90, 16);
		btnv:setFont("font10");
		btnv:setImage("normal", "normal", "click");
		btnv:setLabel("ContinuousV:"..((diamond.consecutive_v and "on") or "off"), 3, 1);
		btnv:setImageColor(unpack(colortable.button));
		btnv:setMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		btnv.onButtonClick = function (this)
			diamond.consecutive_v = not diamond.consecutive_v;
			btnv:setLabel("ContinuousV:"..((diamond.consecutive_v and "on") or "off"), 3, 1);
		end
		background:add(nil, btnv, 101, 105);
	end
	initConsecutive();
	
	local initGenbtn = function ()
		local btn = Girl.View.Button(90, 16);
		btn:setFont("font10");
		btn:setImage("normal", "normal", "click");
		btn:setLabel("Generate", 20, 1);
		btn:setImageColor(unpack(colortable.button));
		btn:setMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		btn.onButtonClick = function (this)
			local co = CreateGenDiamondCo();
			local tic = 0;
			local x, y = gui:getPoint();
			local bx, by = btn:getPoint();
			local bw, bh = btn:getSize();
			local rect = 
			{
				x=x+bx, y=y+by,
				width=bw, height=bh,
			};
			gm:topMost("GenDiamondWnd");
			gm:enableModelmode(true);
			uitable.gen_diamond_wnd:open(2, rect, true);
			
			idle:addTask("GenDiamondNoise", function()
				local status = coroutine.resume(co);
				if status then
					local t = nil
					if tic==0 then t=[[|]];
					elseif tic==1 then t=[[/]];
					elseif tic==2 then t=[[-]];
					else t=[[\]]; end
					
					uitable.gen_diamond_wnd:get("status"):setLabel("Generating..."..t);
					tic = (tic+1)%4;
					return false;
				end
				
				uitable.gen_diamond_wnd:get("status"):setLabel("Update Canvas");
				FinishGenDiamond();
				
				UpdateDiamondGray("DiamondNoise");
				UpdateTerrain("Terrain");
				UpdateShadow("TerrainShadow")
				
				uitable.gen_diamond_wnd:get("status"):setLabel("Finish");
				uitable.gen_diamond_wnd:close(1)
				gm:enableModelmode(false);
				return true;
			end);
		end
		background:add(nil, btn, 101, 125);
	end
	initGenbtn();
	
	local noise_bg = Girl.View.Picture(180,180);
	noise_bg:setImageColor({0,0,0});
	background:add(nil, noise_bg, 10, 150);
	
	local noise_map = Girl.View.Canvas(180,180);
	noise_map:setCanvas("DiamondNoise");
	noise_bg:add(nil, noise_map, 0, 0);
	
	uitable.heightmap_option = gui;
	gui.onMousePressed = function ()
		gm:topMost(tag)
	end
	return tag, gui;
end

function TerrainWnd(graph)
	local cw, ch = 256+10, 256+24;
	local iw, ih = 0, 0;
	local wndbg_w, wndbg_h = 0, 0;
	local diamond = TerrainToy.diamond;
	local heightmap = TerrainToy.heightmap;
	local tag = "Terrain";
	
	graph:createCanvas("TerrainWnd", 512+10, 512+24);
	graph:createCanvas("Terrain", 256, 256);
	graph:createCanvas("TerrainShadow", 256, 256);
	wndbg_w, wndbg_h = graph:getImageSize("wndbg");
	iw, ih = graph:getImageSize("normal");
	
	local gui = Girl.Gui(200, 0, 
		cw, ch, graph, "TerrainWnd");
	
	local background = Girl.View.Picture(cw, ch);
	background:setImage("wndbg");
	background:setImageColor(colortable.background);
	background:setMode(2,{x=20, y=20, width=6, height=6}, wndbg_w, wndbg_h);
	background:enableCaption(true);
	gui:add("bg", background, 0, 0);
	
	local caption = Girl.View.Label(120,16);
	caption:setFont("font12");
	caption:setLabel("Terrain");
	caption.parent_mouse_event = true;
	background:add(nil, caption, 2, 2);
	
	local terrain_bg = Girl.View.Picture(cw-5*2, ch-18-6);
	terrain_bg:setImageColor({0,0,0});
	background:add("terrain_bg", terrain_bg, 5, 19);
	
	local terrain_cv = Girl.View.Canvas(graph:getCanvasSize("Terrain"));
	terrain_cv:setCanvas("Terrain")
	terrain_bg:add("terrain", terrain_cv, 0, 0);
	
	local terrain_sd = Girl.View.Canvas(graph:getCanvasSize("TerrainShadow"));
	terrain_sd:setCanvas("TerrainShadow")
	terrain_cv:add("terrain_sd", terrain_sd, 0, 0);
	local button_down = false;
	terrain_sd.onMousePressed = function (this, x, y, button)
		button_down = true;
		this:grab();
	end
	terrain_sd.onMouseReleased = function (this, x, y, button)
		button_down = false;
		this:ungrab();
	end
	terrain_sd.onMouseMove = function (this, x, y)
		if button_down then
			local cv_w, cv_h = graph:getCanvasSize("Terrain");
		
			heightmap.sun_x = x;
			heightmap.sun_y = cv_h-y;
			UpdateShadow("TerrainShadow");
		end
	end
	
	uitable.terrain_wnd = gui;
	return tag, gui;
end

function TerrainOptionWnd(graph)
	local cw, ch = 200, 110;
	local iw, ih = 0, 0;
	local wndbg_w, wndbg_h = 0, 0;
	local heightmap = TerrainToy.heightmap;
	local tag = "TerrainOption";

	graph:createCanvas("TerrainOption", cw, ch);
	wndbg_w, wndbg_h = graph:getImageSize("wndbg");
	iw, ih = graph:getImageSize("normal");
	
	local gui = Girl.Gui(0, 340, 
		cw, ch, graph, "TerrainOption");
	
	local background = Girl.View.Picture(cw, ch);
	background:setImage("wndbg");
	background:setImageColor(colortable.background);
	background:setMode(2,{x=20, y=20, width=6, height=6}, wndbg_w, wndbg_h);
	background:enableCaption(true);
	gui:add("bg", background, 0, 0);
	
	local caption = Girl.View.Label(180,16);
	caption:setFont("font12");
	caption:setLabel("Terrain Option");
	caption.parent_mouse_event = true;
	background:add(nil, caption, 2, 2);
	
	local initSlider = function ()
		local sliderSea = Girl.View.Slider(100, 14);
		sliderSea:setValue(.3);
		sliderSea:setBackground("click");
		sliderSea:setBackgroundColor(colortable.slider_bg);
		sliderSea:setBackgroundMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		sliderSea:setMode(sliderSea.TypeModeEnum.horizontal,2);
		sliderSea:setSliderRect(8, 1, 84, 11);
		sliderSea:setSliderImage("normal");
		sliderSea:setSliderSize(14,11)
		sliderSea:setSliderColor(unpack(colortable.slider_bar));
		background:add(nil, sliderSea, 70, 25);
		
		local textSea = Girl.View.Label(60,12);
		textSea:setFont("font10");
		textSea:setLabel("Sea level :");
		background:add(nil, textSea, 6, 24);
		
		local valueSea = Girl.View.Label(30, 12);
		valueSea:setFont("font10");
		valueSea:setAlign(valueSea.AlignEnum.right);
		background:add(nil, valueSea, 160, 25);

		local sliderIce = Girl.View.Slider(100, 14);
		sliderIce:setValue(.8);
		sliderIce:setBackground("click");
		sliderIce:setBackgroundColor(colortable.slider_bg);
		sliderIce:setBackgroundMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		sliderIce:setMode(sliderIce.TypeModeEnum.horizontal,2);
		sliderIce:setSliderRect(8, 1, 84, 11);
		sliderIce:setSliderImage("normal");
		sliderIce:setSliderSize(14,11)
		sliderIce:setSliderColor(unpack(colortable.slider_bar));
		background:add(nil, sliderIce, 70, 45);
		
		local textIce = Girl.View.Label(60,12);
		textIce:setFont("font10");
		textIce:setLabel("Ice bound :");
		background:add(nil, textIce, 6, 44);
		
		local valueIce = Girl.View.Label(30, 12);
		valueIce:setFont("font10");
		valueIce:setAlign(valueIce.AlignEnum.right);
		background:add(nil, valueIce, 160, 45);

		sliderSea.onValueChange = function (this)
			local sea_level = floor(sliderSea:getValue()*100)/100;
			local ice_bound = floor(sliderIce:getValue()*100)/100;
			
			if sea_level > ice_bound then
				ice_bound = sea_level;
				sliderIce:setValue(sea_level);
			end
		
			heightmap.sea_level = sea_level;
			heightmap.ice_bound = ice_bound;
			
			valueSea:setLabel(sea_level);
			valueIce:setLabel(ice_bound);
			
			UpdateTerrain("Terrain");
		end
		sliderSea:onValueChange();
		sliderIce.onValueChange = function (this)
			local sea_level = floor(sliderSea:getValue()*100)/100;
			local ice_bound = floor(sliderIce:getValue()*100)/100;
			
			if sea_level > ice_bound then
				sea_level = ice_bound;
				sliderSea:setValue(ice_bound);
			end
		
			heightmap.sea_level = sea_level;
			heightmap.ice_bound = ice_bound;
			
			valueSea:setLabel(sea_level);
			valueIce:setLabel(ice_bound);
			
			UpdateTerrain("Terrain");
		end
		sliderIce:onValueChange();
	end
	initSlider();
	
	local initSunheight = function ()
		local slider = Girl.View.Slider(100, 14);
		slider:setValue(.5);
		slider:setBackground("click");
		slider:setBackgroundColor(colortable.slider_bg);
		slider:setBackgroundMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		slider:setMode(slider.TypeModeEnum.horizontal,2);
		slider:setSliderRect(8, 1, 84, 11);
		slider:setSliderImage("normal");
		slider:setSliderSize(14,11)
		slider:setSliderColor(unpack(colortable.slider_bar));
		background:add(nil, slider, 70, 65);
		
		local text = Girl.View.Label(60,12);
		text:setFont("font10");
		text:setLabel("Sun Height :");
		background:add(nil, text, 6, 64);
		
		local value = Girl.View.Label(30, 12);
		value:setFont("font10");
		value:setAlign(value.AlignEnum.right);
		background:add(nil, value, 160, 65);

		slider.onValueChange = function (this)
			local v = floor(slider:getValue()*10);
			if v==0 then
				v = 1;
			end
			value:setLabel(v);
			if heightmap.sun_h~=v then
				heightmap.sun_h = v;
				UpdateShadow("TerrainShadow");
			end
		end
		slider:onValueChange();
	end
	initSunheight();
	
	local initShadowBtn = function ()
		local btn = Girl.View.Button(90, 16);
		btn:setFont("font10");
		btn:setImage("normal", "normal", "click");
		btn:setLabel(((show_shadow and "Hide Shadow") or "Show Shadow"), 12, 1);
		btn:setImageColor(unpack(colortable.button));
		btn:setMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		btn.onButtonClick = function (this)
			show_shadow = not show_shadow;
			btn:setLabel(((show_shadow and "Hide Shadow") or "Show Shadow"), 12, 1);
			uitable.terrain_wnd:get("bg")
				:get("terrain_bg")
				:get("terrain")
				:get("terrain_sd").show = show_shadow;
		end
		background:add(nil, btn, 10, 85);
	end
	initShadowBtn();
	
	uitable.terrain_option = gui;
	gui.onMousePressed = function ()
		gm:topMost(tag)
	end
	return tag, gui;
end

function PerlinOption(graph)
	local cw, ch = 200, 400
	local iw, ih = 0, 0;
	local wndbg_w, wndbg_h = 0, 0;
	local heightmap = TerrainToy.heightmap;
	local perlin = TerrainToy.perlin;
	local tag = "PerlinOption"
	local offsetx, offsety, scalex, scaley;
	
	graph:createCanvas("PerlinOption", cw, ch);
	graph:createCanvas("PerlinNoise", 256, 256);
	wndbg_w, wndbg_h = graph:getImageSize("wndbg");
	iw, ih = graph:getImageSize("normal");
	
	local gui = Girl.Gui(love.graphics.getWidth()-cw, 0, cw, ch, graph, "PerlinOption");
	
	local background = Girl.View.Picture(cw, ch);
	background:setImage("wndbg");
	background:setImageColor(colortable.background);
	background:setMode(2,{x=20, y=20, width=6, height=6}, wndbg_w, wndbg_h);
	background:enableCaption(true);
	gui:add("bg", background, 0, 0);
	
	local caption = Girl.View.Label(120,16);
	caption:setFont("font12");
	caption:setLabel("Perlin Option");
	caption.parent_mouse_event = true;
	background:add(nil, caption, 2, 2);
	
	local initFrequency = function ()
		local slider = Girl.View.Slider(100, 14);
		slider:setValue(1.0);
		slider:setBackground("click");
		slider:setBackgroundColor(colortable.slider_bg);
		slider:setBackgroundMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		slider:setMode(slider.TypeModeEnum.horizontal,2);
		slider:setSliderRect(8, 1, 84, 11);
		slider:setSliderImage("normal");
		slider:setSliderSize(14,11)
		slider:setSliderColor(unpack(colortable.slider_bar));
		background:add(nil, slider, 70, 25);
		
		local text = Girl.View.Label(60,12);
		text:setFont("font10");
		text:setLabel("Frequency :");
		background:add(nil, text, 6, 24);
		
		local value = Girl.View.Label(30, 12);
		value:setFont("font10");
		value:setAlign(value.AlignEnum.right);
		background:add(nil, value, 160, 25);

		slider.onValueChange = function (this)
			local v = floor(slider:getValue()*100)/100;
			value:setLabel(v);
			perlin.frequency = v;
		end
		slider:onValueChange();
	end
	initFrequency();
	
	local initPersistence = function ()
		local slider = Girl.View.Slider(100, 14);
		slider:setValue(.55);
		slider:setWheelStep(.05);
		slider:setBackground("click");
		slider:setBackgroundColor(colortable.slider_bg);
		slider:setBackgroundMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		slider:setMode(slider.TypeModeEnum.horizontal,2);
		slider:setSliderRect(8, 1, 84, 11);
		slider:setSliderImage("normal");
		slider:setSliderSize(14, 11)
		slider:setSliderColor(unpack(colortable.slider_bar));
		background:add(nil, slider, 70, 45);
		
		local text = Girl.View.Label(60,12);
		text:setFont("font10");
		text:setLabel("Persistence :");
		background:add(nil, text, 6, 44);
		
		local value = Girl.View.Label(30, 12);
		value:setFont("font10");
		value:setAlign(value.AlignEnum.right);
		background:add(nil, value, 160, 45);

		slider.onValueChange = function (this)
			local v = floor(slider:getValue()*100)/100;
			value:setLabel(v);
			perlin.persistence = v;
		end
		slider:onValueChange();
	end
	initPersistence();
	
	local initX = function ()
		local slider = Girl.View.Slider(100, 14);
		slider:setValue(0);
		slider:setWheelStep(.05);
		slider:setBackground("click");
		slider:setBackgroundColor(colortable.slider_bg);
		slider:setBackgroundMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		slider:setMode(slider.TypeModeEnum.horizontal,2);
		slider:setSliderRect(8, 1, 84, 11);
		slider:setSliderImage("normal");
		slider:setSliderSize(14, 11)
		slider:setSliderColor(unpack(colortable.slider_bar));
		background:add(nil, slider, 70, 65);
		
		local text = Girl.View.Label(60,12);
		text:setFont("font10");
		text:setLabel("Offset X :");
		background:add(nil, text, 6, 64);
		
		local value = Girl.View.Label(30, 12);
		value:setFont("font10");
		value:setAlign(value.AlignEnum.right);
		background:add(nil, value, 160, 65);

		slider.onValueChange = function (this)
			local v = floor(slider:getValue()*100);
			value:setLabel(v);
			offsetx = v;
		end
		slider:onValueChange();
	end
	initX();
	
	local initY = function ()
		local slider = Girl.View.Slider(100, 14);
		slider:setValue(0);
		slider:setWheelStep(.05);
		slider:setBackground("click");
		slider:setBackgroundColor(colortable.slider_bg);
		slider:setBackgroundMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		slider:setMode(slider.TypeModeEnum.horizontal,2);
		slider:setSliderRect(8, 1, 84, 11);
		slider:setSliderImage("normal");
		slider:setSliderSize(14, 11)
		slider:setSliderColor(unpack(colortable.slider_bar));
		background:add(nil, slider, 70, 85);
		
		local text = Girl.View.Label(60,12);
		text:setFont("font10");
		text:setLabel("Offset Y :");
		background:add(nil, text, 6, 84);
		
		local value = Girl.View.Label(30, 12);
		value:setFont("font10");
		value:setAlign(value.AlignEnum.right);
		background:add(nil, value, 160, 85);

		slider.onValueChange = function (this)
			local v = floor(slider:getValue()*100);
			value:setLabel(v);
			offsety = v;
		end
		slider:onValueChange();
	end
	initY();
	
	local initScaleX = function ()
		local slider = Girl.View.Slider(100, 14);
		slider:setValue(.01);
		slider:setWheelStep(.01);
		slider:setBackground("click");
		slider:setBackgroundColor(colortable.slider_bg);
		slider:setBackgroundMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		slider:setMode(slider.TypeModeEnum.horizontal,2);
		slider:setSliderRect(8, 1, 84, 11);
		slider:setSliderImage("normal");
		slider:setSliderSize(14, 11)
		slider:setSliderColor(unpack(colortable.slider_bar));
		background:add(nil, slider, 70, 105);
		
		local text = Girl.View.Label(60,12);
		text:setFont("font10");
		text:setLabel("Scale X :");
		background:add(nil, text, 6, 104);
		
		local value = Girl.View.Label(30, 12);
		value:setFont("font10");
		value:setAlign(value.AlignEnum.right);
		background:add(nil, value, 160, 105);

		slider.onValueChange = function (this)
			local v = floor(slider:getValue()*100)/100;
			value:setLabel(v);
			scalex = v;
		end
		slider:onValueChange();
	end
	initScaleX();
	
	local initScaleY = function ()
		local slider = Girl.View.Slider(100, 14);
		slider:setValue(.01);
		slider:setWheelStep(.01);
		slider:setBackground("click");
		slider:setBackgroundColor(colortable.slider_bg);
		slider:setBackgroundMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		slider:setMode(slider.TypeModeEnum.horizontal,2);
		slider:setSliderRect(8, 1, 84, 11);
		slider:setSliderImage("normal");
		slider:setSliderSize(14, 11)
		slider:setSliderColor(unpack(colortable.slider_bar));
		background:add(nil, slider, 70, 125);
		
		local text = Girl.View.Label(60,12);
		text:setFont("font10");
		text:setLabel("Scale X :");
		background:add(nil, text, 6, 124);
		
		local value = Girl.View.Label(30, 12);
		value:setFont("font10");
		value:setAlign(value.AlignEnum.right);
		background:add(nil, value, 160, 125);

		slider.onValueChange = function (this)
			local v = floor(slider:getValue()*100)/100;
			value:setLabel(v);
			scaley = v;
		end
		slider:onValueChange();
	end
	initScaleY();
	
	local initWeight = function ()
		local slider = Girl.View.Slider(100, 14);
		slider:setValue(.01);
		slider:setWheelStep(.01);
		slider:setBackground("click");
		slider:setBackgroundColor(colortable.slider_bg);
		slider:setBackgroundMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		slider:setMode(slider.TypeModeEnum.horizontal,2);
		slider:setSliderRect(8, 1, 84, 11);
		slider:setSliderImage("normal");
		slider:setSliderSize(14, 11)
		slider:setSliderColor(unpack(colortable.slider_bar));
		background:add(nil, slider, 70, 145);
		
		local text = Girl.View.Label(60,12);
		text:setFont("font10");
		text:setLabel("Weight :");
		background:add(nil, text, 6, 144);
		
		local value = Girl.View.Label(30, 12);
		value:setFont("font10");
		value:setAlign(value.AlignEnum.right);
		background:add(nil, value, 160, 145);

		slider.onValueChange = function (this)
			local v = floor(slider:getValue()*100)/100;
			value:setLabel(v);
			TerrainToy.perlin_weight = v;
		end
		slider:onValueChange();
	end
	initWeight();
	
	local initRandomSeed = function()
		local text = Girl.View.Label(60,12);
		text:setFont("font10");
		text:setLabel("Rand Seed :");
		background:add(nil, text, 6, 165);
	
		local editbox = Girl.View.EditBox(120, 14);
		editbox:setFont("font10");
		editbox:setBorder("click");
		editbox:setBorderColor(colortable.slider_bg);
		editbox:setMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		editbox:setTextRect(2,0, 120-4, 14)
		editbox:setLimit(true, 10);
		editbox.onTextChange = function (this)
			TerrainToy.perlin_seed = tonumber(this:getText());
		end
		background:add(nil, editbox, 70, 165);
	end
	initRandomSeed();
	
	local initGenbtn = function ()
		local btn = Girl.View.Button(90, 16);
		btn:setFont("font10");
		btn:setImage("normal", "normal", "click");
		btn:setLabel("Generate", 20, 1);
		btn:setImageColor(unpack(colortable.button));
		btn:setMode(2,{x=4, y=4, width=12, height=12}, iw, ih);
		btn.onButtonClick = function (this)
			local co = CreateGenPerlinCo(offsetx, offsety, scalex, scaley);
			local x, y = gui:getPoint();
			local bx, by = btn:getPoint();
			local bw, bh = btn:getSize();
			local rect = 
			{
				x=x+bx, y=y+by,
				width=bw, height=bh,
			};
			gm:topMost("GenPerlinWnd");
			gm:enableModelmode(true);
			uitable.gen_perlin_wnd:open(2, rect, true);
			
			idle:addTask("GenPerlinNoise", function()
				local status, _, pre = coroutine.resume(co);
				if status then
					uitable.gen_perlin_wnd:get("bg"):get("progress"):setValue(pre/TerrainToy.diamond.map_dimension);
					return false;
				end
				
				uitable.gen_perlin_wnd:get("bg"):get("progress"):setValue(1);
				FinishGenPerlin();
				
				UpdatePerlinGray("PerlinNoise");
				UpdateTerrain("Terrain");
				UpdateShadow("TerrainShadow")
				
				uitable.gen_perlin_wnd:close(1)
				gm:enableModelmode(false);
	
				return true;
			end);
		end
		background:add(nil, btn, 101, 185);
	end
	initGenbtn();
	
	local noise_bg = Girl.View.Picture(180,180);
	noise_bg:setImageColor({0,0,0});
	background:add(nil, noise_bg, 10, 210);
	
	local noise_map = Girl.View.Canvas(180,180);
	noise_map:setCanvas("PerlinNoise");
	noise_bg:add(nil, noise_map, 0, 0);
	
	uitable.perlin_option = gui;
	gui.onMousePressed = function ()
		gm:topMost(tag)
	end
	return tag, gui;
end
